package com.model.demo.spring.framework.webmvc.servlet;

import com.model.demo.spring.mini.mvcframework.annotation.MyRequestParam;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.annotation.Annotation;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;

public class MyHandlerAdapter {

    public boolean supports(Object handler){
        return handler instanceof MyHandleMapping;
    }

    public MyModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception{
        MyHandleMapping handleMapping= (MyHandleMapping) handler;

        Map<String,Integer> paramsIndexMapping = new HashMap<>();

        //处理形参
        //处理MyRequestMapping注解形参
        Annotation[][] parameterAnnotations = handleMapping.getMethod().getParameterAnnotations();
        for (int i = 0; i < parameterAnnotations.length; i++) {
            for (Annotation annotation : parameterAnnotations[i]) {
                if(annotation instanceof MyRequestParam){
                    MyRequestParam myRequestMapping = (MyRequestParam) annotation;
                    String value = myRequestMapping.value();
                    paramsIndexMapping.put(value, i);
                }
            }
        }
        //处理特殊类型形参
        Class<?>[] parameterTypes = handleMapping.getMethod().getParameterTypes();
        for (int i = 0; i < parameterTypes.length; i++) {
            if(parameterTypes[i] == HttpServletRequest.class
                ||parameterTypes[i] == HttpServletResponse.class){
                paramsIndexMapping.put(parameterTypes[i].getSimpleName(), i);
            }

        }

        Map<String, String[]> parameterMap = request.getParameterMap();
//        Class<?>[] parameterTypes = handleMapping.getMethod().getParameterTypes();
        Object [] paramsValue = new Object[parameterTypes.length];
        for (Map.Entry<String, String[]> entry : parameterMap.entrySet()) {
            if(paramsIndexMapping.containsKey(entry.getKey())){
                int index = paramsIndexMapping.get(entry.getKey());
                String value = Arrays.toString(entry.getValue()).replaceAll("\\[|\\]", "");
                paramsValue[index] = convert(parameterTypes[index], value);

            }
//
        }
        if(paramsIndexMapping.containsKey(HttpServletRequest.class.getSimpleName())){
            int  index = paramsIndexMapping.get(HttpServletRequest.class.getSimpleName());
            paramsValue[index] = request;
        }
        if(paramsIndexMapping.containsKey(HttpServletResponse.class.getSimpleName())){
            int  index = paramsIndexMapping.get(HttpServletResponse.class.getSimpleName());
            paramsValue[index] = response;
        }

        Object result = handleMapping.getMethod().invoke(handleMapping.getController(), paramsValue);

        if(result==null){return null;}

        boolean isModelAndView = handleMapping.getMethod().getReturnType()==MyModelAndView.class;
        if(isModelAndView){return (MyModelAndView) result;}
        return null;
    }

    //url传过来的参数都是String类型的，HTTP是基于字符串协议
    //只需要把String转换为任意类型就好
    private Object convert(Class<?> type,String value){
        if(Integer.class == type){
            return Integer.valueOf(value);
        }
        //如果还有double或者其他类型，继续加if
        //这时候，我们应该想到策略模式了
        //在这里暂时不实现，希望小伙伴自己来实现
        return value;
    }
}
